package com.loren.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.loren.constant.DataSourceContant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.util.StringUtils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

public class DynamicDatasouce extends AbstractRoutingDataSource {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${custom.default.datasource.db-url}")
    private String databaseUrl;

    @Value("${custom.default.datasource.db-user-name}")
    private String dbUserName;

    @Value("${custom.default.datasource.db-password}")
    private String dbPassword;

    private Map<Object, Object> dataSourceMap = new HashMap<>();

    @Override
    protected Object determineCurrentLookupKey() {
        String targetDataSource = DynamicDataSourceHolder.getDataSourceType();
        if (!StringUtils.isEmpty(targetDataSource) && !DataSourceContant.DEFAULT_DATASOURCE.equals(targetDataSource)) {
            if (!this.dataSourceMap.containsKey(targetDataSource)) {
                DruidDataSource newDataSource = this.createDataSource(targetDataSource);
                if(newDataSource != null) {
                    this.dataSourceMap.put(targetDataSource, newDataSource);
                    super.setTargetDataSources(this.dataSourceMap);
                    super.afterPropertiesSet();
                }
            }
        }
        return targetDataSource;
    }

    private DruidDataSource createDataSource(String targetDataSource) {
        String selectDataSourceSQL = "SELECT * FROM db_info WHERE data_source_id = " + Integer.parseInt(targetDataSource);
        logger.info("selectDataSourceSQL = {}", selectDataSourceSQL);
        try (
                Connection connection = DriverManager.getConnection(this.databaseUrl, this.dbUserName, this.dbPassword);
                PreparedStatement statement = connection.prepareStatement(selectDataSourceSQL);
                ResultSet resultSet = statement.executeQuery();
        ) {
            if (resultSet.next()) {
                DruidDataSource dataSource = new DruidDataSource();
                dataSource.setDriverClassName(resultSet.getString("db_driver"));
                dataSource.setUrl(resultSet.getString("db_url"));
                dataSource.setUsername(resultSet.getString("db_user"));
                dataSource.setPassword(resultSet.getString("db_pass"));
                dataSource.setMaxActive(10);
                dataSource.setMaxWait(10000);
                dataSource.setValidationQuery("SELECT 1");
                dataSource.setFilters("config, stat");
                dataSource.setTestOnBorrow(true);
                return dataSource;
            }
        } catch (Exception e) {
            logger.error("create data source error", e);
        }
        return null;
    }
}
